{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Attribute Write Accessors"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As we saw in the lecture there is one special method for attribute writes: `__setattribute__`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's just see when it gets called:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Person:\n",
    "    def __setattr__(self, name, value):\n",
    "        print('setting instance attribute...')\n",
    "        super().__setattr__(name, value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "p = Person()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "setting instance attribute...\n"
     ]
    }
   ],
   "source": [
    "p.name = 'Guido'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Of course, if we set a class attribute it does not get called:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "Person.class_attr = 'test'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In order to override this setter for class attributes we would have to define it in the metaclass:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "class MyMeta(type):\n",
    "    def __setattr__(self, name, value):\n",
    "        print('setting class attribute...')\n",
    "        return super().__setattr__(name, value)\n",
    "    \n",
    "class Person(metaclass=MyMeta):\n",
    "    def __setattr__(self, name, value):\n",
    "        print('setting instance attribute...')\n",
    "        super().__setattr__(name, value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "setting class attribute...\n"
     ]
    }
   ],
   "source": [
    "Person.test = 'test'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "setting instance attribute...\n"
     ]
    }
   ],
   "source": [
    "p = Person()\n",
    "p.test = 'test'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And as we discussed in the lecture, if our `__setattr__` is setting a **data** descriptor, then it calls the descriptor's `__set__` method instead:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "class MyNonDataDesc:\n",
    "    def __get__(self, instance, owner_class):\n",
    "        print('__get__ called on non-data descriptor...')\n",
    "        \n",
    "class MyDataDesc:\n",
    "    def __set__(self, instance, value):\n",
    "        print('__set__ called on data descriptor...')\n",
    "        \n",
    "    def __get__(self, instance, owner_class):\n",
    "        print('__get__ called on data descriptor...')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "class MyClass:\n",
    "    non_data_desc = MyNonDataDesc()\n",
    "    data_desc = MyDataDesc()\n",
    "    \n",
    "    def __setattr__(self, name, value):\n",
    "        print('__setattr__ called...')\n",
    "        super().__setattr__(name, value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "m = MyClass()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{}"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.__dict__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "__setattr__ called...\n",
      "__set__ called on data descriptor...\n"
     ]
    }
   ],
   "source": [
    "m.data_desc = 100"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "__setattr__ called...\n"
     ]
    }
   ],
   "source": [
    "m.non_data_desc = 200"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'non_data_desc': 200}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.__dict__"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "So `__setattr__` can be used to intercept and customize any attribute set operation on the instance that the method is defined for."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Just as with `__getattr__` or `__getattribute__` we have to extra careful with infinite recursion."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Suppose we want to disallow setting values for variables that start with a single underscore (but not a double underscore). We might try something like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "class MyClass:\n",
    "    def __setattr__(self, name, value):\n",
    "        print('__setattr__ called...')\n",
    "        if name.startswith('_') and not name.startswith('__'):\n",
    "            raise AttributeError('Sorry, this attribute is read-only.')\n",
    "        setattr(self, name, value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "m = MyClass()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This works fine:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "__setattr__ called...\n",
      "Sorry, this attribute is read-only.\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    m._test = 'test'\n",
    "except AttributeError as ex:\n",
    "    print(ex)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "But this will not:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "__setattr__ called...\n",
      "maximum recursion depth exceeded while calling a Python object\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    m.test = 'test'\n",
    "except RecursionError as ex:\n",
    "    print(ex)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And of course this is because the line `self.name = value` we have in `__setattr__` is itself calling `__setattr__`. So instead, we have to delegate this back to the parent:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "class MyClass:\n",
    "    def __setattr__(self, name, value):\n",
    "        print('__setattr__ called...')\n",
    "        if name.startswith('_') and not name.startswith('__'):\n",
    "            raise AttributeError('Sorry, this attribute is read-only.')\n",
    "        super().__setattr__(name, value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "m = MyClass()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "__setattr__ called...\n"
     ]
    }
   ],
   "source": [
    "m.test = 'test'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'test': 'test'}"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.__dict__"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "So, just as with the getters, when we want to actually get to the attributes in our instance, we just need to distinguish wether we want the default way of getting/setting the attribute, or our custom override, and use `super()` accordingly. As long as you remember that, you should be fine :-)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
